var ElComponents = {}

/**
 * Vue.use(vui365) 安装函数
 * see: [Vue.use()用法](https://www.cnblogs.com/xiao1314/p/14426569.html)
 */
ElComponents.install = function (Vue, option) {
  //  注册组件
  Vue.component("CaptchaImage", ElComponents.CaptchaImage)
  Vue.component("MessagesPanel", ElComponents.MessagesPanel)
  Vue.component("TableSearchPanel", ElComponents.TableSearchPanel)
  Vue.component("TableToolbar", ElComponents.TableToolbar)
  Vue.component("ExcelUploadDialog", ElComponents.ExcelUploadDialog)
  // 全局属性使用 gp 前缀。gp = global prototype 的意思。
  // Vue.config.globalProperties.gpEsConfig = EsConfig;
}

/**
 * 文件上传对话框
 */
ElComponents.ExcelUploadDialog = {
  template: `<el-dialog
    :title="title"
    :visible="visible"
    width="410px"
    @close="$emit('update:visible',false)"
    center
  >
    <div style="text-align: center">
      <el-upload
        drag
        action="https://jsonplaceholder.typicode.com/posts/"
        multiple
        :on-success="onUploadSuccess"
        :on-error="onUploadError"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">
          {{ tip }}
          <a href="#" target="_blank" class="btn-link">下载模板</a>
        </div>
      </el-upload>
    </div>
  </el-dialog>`,
  name: "ExcelUploadDialog",
  emits: ["uploaded"],
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    // 是否支持多选文件
    multiple: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: "导入数据",
    },
    // 提示信息: 只能上传jpg/png文件，且不超过500kb
    tip: {
      type: String,
      default: "只能上传xls、xlsx文件",
    },
    // 上传文件服务端处理地址
    actionUrl: {
      type: String,
      default: "",
    },
    // 上传的文件字段名
    name: {
      type: String,
      default: "file",
    },
    // 设置上传的请求头部
    headers: {
      type: Object,
      default() {
        return {};
      },
    },
    // 上传时附带的额外参数
    data: {
      type: Object,
      default() {
        return {};
      },
    },
    // Excel 模板文件路径
    templatePath: {
      type: String,
      default: "",
    },
  },
  methods: {
    // 文件上传成功
    onUploadSuccess(response, file, fileList) {
      console.log("[UploadDialog] 文件上传成功 response = ", response);
      this.$emit("uploaded", true, response, file, fileList);
      // this.$emit('update:visible',false)
    },
    // 文件上传失败
    onUploadError(err, file, fileList) {
      console.log("[UploadDialog] 文件上传失败 err = ", err);
      this.$emit("uploaded", false, err, file, fileList);
    },
  },
};

/**
 * 数据表工具栏组件
 */
ElComponents.TableToolbar = {
  template: `<div class="d-flex justify-content-between">
        <el-button-group>
            <el-button type="primary" size="mini" @click="onClickToolbar('create')">新增</el-button>
            <el-button type="danger" size="mini" @click="onClickToolbar('delete-multi')">删除</el-button>
            <el-button v-show="editMultiVisible" type="info" size="mini" @click="onClickToolbar('edit-multi')">修改
            </el-button>
            <el-button v-show="copyMultiVisible" type="info" size="mini" @click="onClickToolbar('copy-multi')">复制
            </el-button>
        </el-button-group>
        <el-button-group>
            <el-button type="info" size="mini" :loading="loadingOfRefresh" @click="onClickToolbar('refresh')">刷新
            </el-button>
            <el-button v-show="importVisible" type="info" size="mini" @click="onClickToolbar('import')">导入</el-button>
            <el-button v-show="exportVisible" type="info" size="mini" @click="onClickToolbar('export')">导出</el-button>
            <el-button type="info" size="mini" @click="onClickToolbar('print')">
                打印
            </el-button>
            <el-button type="info" size="mini" @click="onClickToolbar('fullscreen')">全屏</el-button>
            <el-dropdown :hide-on-click="false">
                <el-button type="info" size="mini">
                    列<i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item v-for="(item, idx) of columns" :key="idx">
                        <el-checkbox v-model="item.visible" :label="item.title" @change="onChangeVisible()">
                        </el-checkbox>
                    </el-dropdown-item>
                </el-dropdown-menu>
            </el-dropdown>
        </el-button-group>
        <!-- 导入excel弹窗 -->
        <excel-upload-dialog :visible="false" title="导入数据" @uploaded="onUpload"></excel-upload-dialog>
    </div>
</template>`,
  name: 'TableToolbar',
  emits: ['click'],
  props: {
    titleOfPrint: {
      type: String,
      default: '页面标题',
    },
    loadingOfRefresh: {
      type: Boolean,
      default: false,
    },
    columns: {
      type: Object,
      default() {
        return {};
      }
    },
    editMultiVisible: {
      type: Boolean,
      default: false,
    },
    copyMultiVisible: {
      type: Boolean,
      default: false
    },
    importVisible: {
      type: Boolean,
      default: false
    },
    exportVisible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      visibleOfUploadDialog: false,
    }
  },
  methods: {
    onChangeVisible() {
      this.$emit(`update:columns`, this.columns);
    },
    onClickToolbar(name, item) {
      console.log("[TableToolbar.onClickToolbar] ", name, item);
      switch (name) {
        case "create":
          // console.log('点击按钮 工具栏 - 新增');
          break;
        case "edit-multi":
          // console.log('点击按钮 工具栏 - 批量编辑');
          break;
        case "copy-multi":
          // console.log('点击按钮 工具栏 - 批量复制');
          break;
        case "delete-multi":
          // console.log('点击按钮 工具栏 - 批量删除');
          break;
        case "import":
          console.log('点击按钮 工具栏 - 导入');
          this.visibleOfUploadDialog = true;
          console.log("visibleOfUploadDialog", this.visibleOfUploadDialog);
          break;
        case "export":
          // console.log('点击按钮 工具栏 - 导出');
          break;
        case "refresh":
          // console.log('点击按钮 工具栏 - 刷新');
          // this.$emit('update:loadingOfRefresh',true);
          // this.loadData();
          break;
        case "fullscreen":
          console.log('点击按钮 工具栏 - 全屏');
          // 显示器全屏
          if (document.fullscreenElement) {
            document.exitFullscreen();
          } else {
            document.querySelector(".card-table").requestFullscreen();
          }
          break;
        case "print":
          console.log('点击按钮 工具栏 - 打印');
          // document.title = document.querySelector("h4").innerText;
          document.title = this.titleOfPrint;
          window.print();
          break;
        default:
          break;
      }
      this.$emit('click', name, item);
    },
    // 导入文件操作
    onUpload(success, ret) {
      if (!success) {
        this.$message.error(ret.message);
        return;
      }
      console.log("上传成功 ", ret);
    },
  }
}

/**
 * 数据表搜索面板组件
 */
ElComponents.TableSearchPanel = {
  template: `<el-card class="mb-2 card-sm card-search">
    <div slot="header" class="d-flex justify-content-between">
      <h4>{{ title }}</h4>
      <el-switch v-model="visibleOfSearchPanel" :inactive-text="visibleOfSearchPanel ? '高级搜索' : '精简搜索'">
      </el-switch>
    </div>
    <el-form v-show="!visibleOfSearchPanel" :inline="true" :model="dataOfSearch" class="search-simple" size="mini">
      <el-form-item label="关键词">
        <el-input v-model="dataOfSearch.keyword" :placeholder="placeholder"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :loading="loadingOfSearch" @click="onSearch()">模糊查询</el-button>
      </el-form-item>
    </el-form>
    <div v-show="visibleOfSearchPanel">
      <slot name="default">
        <el-form :inline="true" :model="dataOfSearch" size="mini">
          <el-form-item label="活动区域">
            <el-select v-model="dataOfSearch.region" placeholder="请选择活动区域">
              <el-option label="区域一" value="shanghai"></el-option>
              <el-option label="区域二" value="beijing"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="活动时间">
            <el-date-picker v-model="dataOfSearch.date" type="datetime" placeholder="选择日期时间">
            </el-date-picker>
          </el-form-item>
          <el-form-item label="活动时间">
            <el-date-picker v-model="dataOfSearch.dateRange" type="datetimerange" range-separator="至"
              start-placeholder="开始日期" end-placeholder="结束日期">
            </el-date-picker>
          </el-form-item>
          <el-form-item label="即时配送">
            <el-switch v-model="dataOfSearch.delivery"></el-switch>
          </el-form-item>
          <el-form-item label="活动性质">
            <el-checkbox-group v-model="dataOfSearch.type">
              <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
              <el-checkbox label="地推活动" name="type"></el-checkbox>
              <el-checkbox label="线下主题活动" name="type"></el-checkbox>
              <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
            </el-checkbox-group>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :loading="loadingOfSearch" @click="onSearch()">查询</el-button>
          </el-form-item>
        </el-form>
      </slot>
    </div>
  </el-card>`,
  name: 'TableSearchPanel',
  props: {
    title: {
      type: String,
      default: '页面标题'
    },
    placeholder: {
      type: String,
      default: 'ID/名称',
    },
  },
  data() {
    return {
      visibleOfSearchPanel: false,
      loadingOfSearch: false,
      // 查询数据
      dataOfSearch: {
        keyword: "",
        name: "",
        region: "",
        date1: "",
        date2: "",
        delivery: false,
        type: [],
        resource: "",
        desc: "",
      },

    }
  },
  methods: {

  }
}


/**
 * 消息面板
 * 用于首页侧边栏
 */
ElComponents.MessagesPanel = {
  template: `<div>
    <el-drawer :visible="visible" direction="rtl" @close="onCloseDialog('drawer')">
      <el-tabs type="border-card">
        <el-tab-pane label="通知 (0)">
          <el-empty description="没有通知" v-if="dataOfNotices.length == 0"></el-empty>
          <div v-else>
            <div class="d-flex">
              <el-button-group>
                <el-button type="primary" size="mini" @click="onClickToolbar('create')">标记已读</el-button>
                <el-button type="danger" size="mini" @click="onClickToolbar('delete-multi')">删除</el-button>
              </el-button-group>
            </div>
            <el-table :data="dataOfNotices" stripe style="width: 100%">
              <el-table-column type="selection" width="55"> </el-table-column>
              <el-table-column>
                <template slot-scope="scope">
                  <div :class="scope.row.status == 0 ? 'fw-bold' : ''">
                    {{ scope.row.title }}
                  </div>
                  <div class="d-flex justify-content-between align-items-center">
                    <div>{{ scope.row.created_at }}</div>
                    <el-button-group>
                      <el-button type="text" @click="onClickToolbar('notices-detail')">查看</el-button>
                      <el-button type="text" class="ms-2">删除</el-button>
                    </el-button-group>
                  </div>
                </template>
              </el-table-column>
            </el-table>
            <div class="mt-2">
              <el-pagination background layout="prev, pager, next" :total="1000" :pager-count="5">
              </el-pagination>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="消息 (0)">
          <el-empty description="没有消息" v-if="dataOfNotices.length == 0"></el-empty>
          <div v-else>
            <div class="d-flex">
              <el-button-group>
                <el-button type="primary" size="mini" @click="onClickToolbar('create')">标记已读</el-button>
                <el-button type="danger" size="mini" @click="onClickToolbar('delete-multi')">删除</el-button>
              </el-button-group>
            </div>
            <el-table :data="dataOfNotices" stripe style="width: 100%">
              <el-table-column type="selection" width="55"> </el-table-column>
              <el-table-column>
                <template slot-scope="scope">
                  <div :class="scope.row.status == 0 ? 'fw-bold' : ''">
                    {{ scope.row.title }}
                  </div>
                  <div>{{ scope.row.created_at }}</div>
                </template>
              </el-table-column>
            </el-table>
            <div class="mt-2">
              <el-pagination background layout="prev, pager, next" :total="1000" :pager-count="5">
              </el-pagination>
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="代办 (0)">
          <el-empty description="没有代办事项" v-if="dataOfNotices.length == 0"></el-empty>
          <div v-else>
            <div class="d-flex">
              <el-button-group>
                <el-button type="primary" size="mini" @click="onClickToolbar('create')">标记已读</el-button>
                <el-button type="danger" size="mini" @click="onClickToolbar('delete-multi')">删除</el-button>
              </el-button-group>
            </div>
            <el-table :data="dataOfNotices" stripe style="width: 100%">
              <el-table-column type="selection" width="55"> </el-table-column>
              <el-table-column>
                <template slot-scope="scope">
                  <div :class="scope.row.status == 0 ? 'fw-bold' : ''">
                    {{ scope.row.title }}
                  </div>
                  <div>
                    {{ scope.row.created_at }}
                    <el-link type="primary">删除</el-link>
                    <el-link type="primary">回复</el-link>
                  </div>
                </template>
              </el-table-column>
            </el-table>
            <div class="mt-2">
              <el-pagination background layout="prev, pager, next" :total="1000" :pager-count="5">
              </el-pagination>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-drawer>

    <!-- 表单对话框 -->
    <el-dialog title="收货地址" :visible.sync="visibleOfDialog">
      <el-form :model="form">
        <el-form-item label="活动名称" label-width="120px">
          <el-input v-model="form.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="活动区域" label-width="120px">
          <el-select v-model="form.region" placeholder="请选择活动区域">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>
  </div>`,
  name: "MessagesPanel",
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      // 通知数据
      dataOfNotices: [
        {
          id: 1,
          title: "今天大雨，大家下班早点回家",
          created_at: "2022-07-15 16:00:00",
          status: 0,
        },
        {
          id: 2,
          title: "发工资啦，520快到了，大家省点花钱",
          created_at: "2022-07-15 16:00:00",
          status: 1,
        },
      ],
      visibleOfDialog: false,
      form: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
      },
    };
  },
  methods: {
    onClickToolbar(name, data) {
      switch (name) {
        case 'notices-detail':
          this.visibleOfDialog = true;
          break;
        case 'messages-detail':
          this.visibleOfDialog = true;
          break;
        case 'todos-detail':
          this.visibleOfDialog = true;
          break;
      }
    },
    onCloseDialog(name) {
      console.log('关闭弹窗', name);
      this.$emit('update:visible', false)
    }
  }
};
/**
 * 图形验证码组件
 * @version 1.0.0
 */
ElComponents.CaptchaImage = {
  name: "CaptchaImage",
  props: {
    // 图片宽度
    width: { type: Number, default: 150 },
    // 图片高度
    height: { type: Number, default: 39 },
    // 边框圆角
    round: { type: Number, default: 2 },
    // 字符集
    codeSet: {
      type: Array,
      default() {
        return [..."2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY"];
      },
    },
    // 验证码字体
    fontTtf: { type: String, default: "微软雅黑" },
    // 验证码字体大小(px)
    fontSize: { type: String, default: "23px" },
    // 验证码过期时间（s）
    expire: { type: Number, default: 1800 },
    // 验证码位数
    length: { type: Number, default: 4 },
    // 是否添加杂点
    useNoise: { type: Boolean, default: true },
    // 是否画混淆曲线
    useCurve: { type: Boolean, default: true },
    // 背景颜色
    background: { type: String, default: "white" },
    // 是否输出调试信息
    isDebug: { type: Boolean, default: false },
    // 超级代码
    superCode: { type: String, default: "o01l" },
  },
  data() {
    return {};
  },
  methods: {
    // 实例化组件
    initializeComponent() {
      this.$refs.captcha.style.cssText = `width:${this.width}px; height:${this.height}px; border-radius:${this.round}px;`;
      let characters = [];
      this.draw(this.$refs.captcha, characters);
      this.log(characters);
      this.$refs.captcha.onclick = () => {
        this.draw(this.$refs.captcha, characters);
        this.log(characters);
      };
      this.value = characters.join("").trim();
      return characters;
    },
    /**
     * 刷新验证码
     */
    refresh() {
      this.log("refresh");
      this.initializeComponent();
    },
    /**
     * 检测验证码是否正确
     * @param {String} text 验证码
     * @param {Boolean} ignoreCase 是否忽略大小写
     */
    check(text, ignoreCase = true) {
      if (this.isDebug && text == this.superCode) {
        return true;
      }
      let result = false;
      if (ignoreCase) {
        result =
          text.length > 0 && text.toLowerCase() == this.value.toLowerCase();
      } else {
        result = text.length > 0 && text == this.value;
      }
      this.log("text=", text, "&value=", this.value, "&result=", result);
      return result;
    },
    log(...args) {
      if (this.isDebug) {
        console.log("[ImageCaptcha] ", ...args);
      }
    },
    // 绘制图形验证码
    draw(el, characters) {
      let width = el.clientWidth;
      let height = el.clientHeight;
      el.width = width;
      el.height = height;
      let context = el.getContext("2d");
      if (this.background) {
        //绘制矩形，作背景色
        context.fillStyle = this.background;
        //绘制实心矩形
        context.fillRect(0, 0, width, height);
      }
      let codeSet = this.codeSet;
      //codeSet = [...'们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高'];
      //codeSet = [...'量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全'];
      //codeSet = [...'组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立'];
      //codeSet = [...'题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复'];
      //codeSet = [...'安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术'];
      //codeSet = [...'状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记'];
      let sLength = codeSet.length;
      // 验证码字体样式
      let fontStyle = `bold ${this.fontSize} ${this.fontTtf}`;
      // 验证码位数
      let len = this.length;
      for (let i = 0; i < len; i++) {
        let j = Math.floor(Math.random() * sLength); // 随机索引
        let deg = (Math.random() * 30 * Math.PI) / 180; // 0-30随机弧度
        let text = codeSet[j]; // 随机字符
        characters[i] = text;
        let x = 10 + i * 20; // x坐标
        let y = 20 + Math.random() * 8; // y坐标
        // 位移，旋转角度，颜色，文字，样式，起始位置
        context.font = fontStyle;
        context.translate(x, y);
        context.rotate(deg);
        context.fillStyle = this.randomColor();
        context.fillText(text, 0, 0);
        // 复位
        context.rotate(-deg);
        context.translate(-x, -y);
      }
      // 添加杂点
      if (this.useNoise) {
        for (let i = 0; i <= 30; i++) {
          context.strokeStyle = this.randomColor();
          context.beginPath(); // 开始路径
          let m = Math.random() * width;
          let n = Math.random() * height;
          context.moveTo(m, n);
          context.lineTo(m + 1, n + 1);
          context.stroke(); // 画出上面定义好的路径
        }
      }

      if (this.useCurve) {
        for (let i = 0; i < 8; i++) {
          context.strokeStyle = this.randomColor();
          context.beginPath();
          context.moveTo(Math.random() * width, Math.random() * height);
          context.lineTo(Math.random() * width, Math.random() * height);
          context.stroke();
        }
      }
    },
    // 生成随机颜色
    randomColor() {
      let rgb = {
        r: Math.floor(Math.random() * 256),
        g: Math.floor(Math.random() * 256),
        b: Math.floor(Math.random() * 256),
      };
      return `rgb(${rgb.r},${rgb.g},${rgb.b})`;
    },
  },
  mounted() {
    this.initializeComponent();
  },
  template: `<canvas
    ref="captcha"
    title="点击图片更换验证码"
  ></canvas>`,
}
